#include "main.h"

#if defined(BAD_EXAMPLE) || defined(STEAL_WILLROCKS_HASH)
void Foo( char * thing, int len ) {
	//std::cout << "calling foo" << std::endl;
	int i = 0;
	len--;
	while ( i <= len / 2 ) { 
		char temp = thing[i];
		thing[i] = thing[len - i];
		thing[len - i] = temp;
		i++;
	}
}

// depending on implementation, pauses and extracting/inputting to streams has some weird behavior
// need less optimizations for HiLo to work in this case
void Bar( char * thing, int len ) {
	Foo( thing, len );
}

int main( size_t argc, char ** argv ) {
	if ( argc == 3 ) {
		printf( "%08X\n", Foo );
		printf( "%08X\n", Bar );
	}

	system("PAUSE");

	if ( argc >= 2 ) {
		std::cout << argv[1] << std::endl;
		Bar( argv[1] , strlen(argv[1]) );
		std::cout << argv[1] << std::endl;
	}

	system("PAUSE");
	return 0;
}

#else

volatile int doLoop = 1;

// example function
// trace into a made call to this function
// takes 3 values:
//	EAX:				offset
//	EBX:				size
//	first arg on stack:	index
// and returns with:
//	ESI <- calculated address (offset + size << index)
//	EDI <- offset
//	performs some muddling with the stack
//		push and immediate pop to show some support for common stack operations
// puts in doLoop the result of the calculation
void __declspec( naked ) Foo( void ) {
	__asm {
		MOV CL, BYTE PTR SS:[ESP + 4]
		MOV EDI, EBX
		SHL EDI, CL
		ADD EDI, EAX
		PUSH EDI
		POP ESI
		MOV EDI, EAX
		MOV doLoop, ESI
		RET
	}
}

int main( size_t argc, char ** argv ) {
	if ( argc == 2 ) {
		printf( "%08X\n", Foo );
	}

	printf( "doLoop is at %08X and Foo is at %08X.\nBet you can't use Foo to turn off doLoop.\nFoo takes in 3 arguments (EAX,EBX,and on the stack)\n", &doLoop, &Foo );

	while ( doLoop ) {

	}

	system("PAUSE");
	return 0;
}

#endif